package com.monochromebytes.mononet.test;

import org.newdawn.slick.geom.Shape;
import org.newdawn.slick.geom.Transform;
import org.newdawn.slick.geom.Vector2f;

public class Body extends Collidable {
    
    private static final long serialVersionUID = 3254921282073389548L;

    private Vector2f velocity         = new Vector2f(0, 0);
    private float    mass             = 1.0f;
    private float    angularFrequency = 0;
    private float    momentOfInertia;
    
    

    public void init(Shape shape, Vector2f velocity, float angularFrequency, float mass) {
        super.init(shape);

        this.calculateMomentOfInertia();
        this.velocity.set(velocity);
        this.angularFrequency = angularFrequency;
        this.mass = mass;
    }

    @Override
    public Shape calculateShape(Shape shape, float delta) {
        // calculate Movement
        if (this.velocity.x != 0 || this.velocity.y != 0) {
            Vector2f way = this.velocity.copy().scale(delta);
            Transform movement = Transform.createTranslateTransform(way.x, way.y);
            shape = shape.transform(movement);
        }

        // calculate Torque
        float deltaAngle = (this.angularFrequency * delta) % (float) (2 * Math.PI);
        if (deltaAngle != 0) {
            Transform rotation = Transform.createRotateTransform(deltaAngle, shape.getCenterX(),
                    shape.getCenterY());
            shape = shape.transform(rotation);
        }
        shape.preCache();
        return shape;
    }

    public float getAngularFrequency() {
        return this.angularFrequency;
    }

    public void setAngularFrequency(float frequency) {
        this.angularFrequency = frequency;
    }

    public float getMass() {
        return this.mass;
    }

    public void setMass(float mass) {
        this.mass = mass;
    }

    private void calculateMomentOfInertia() {
        Shape shape = super.getShape();
        int points = shape.getPointCount();
        Vector2f center = new Vector2f(shape.getCenter());

        int sum1 = 0;
        int sum2 = 0;
        for (int n = 0; n < points; n++) {
            Vector2f pointN = new Vector2f(shape.getPoint(n));
            Vector2f pointNp1 = new Vector2f(shape.getPoint((n + 1) % (points)));

            pointN.sub(center);
            pointNp1.sub(center);

            double cross = (pointNp1.x * pointN.y) - (pointNp1.y * pointN.x);
            sum1 += cross * (pointN.dot(pointN) + pointN.dot(pointNp1) + pointNp1.dot(pointNp1));
            sum2 += cross;
        }

        this.momentOfInertia = (this.mass / 6) * (sum1 / sum2);
    }

    public float getInertia() {
        return this.momentOfInertia;
    }

    public Vector2f getVelocity() {
        return this.velocity.copy();
    }

    public void setVelocity(Vector2f velocity) {
        this.velocity.set(velocity);
    }
}
